package com.example.demo.controller;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang3.StringUtils;
import org.json.JSONException;
import org.json.XML;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.querydsl.QPageRequest;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.example.demo.framework.CustomPage;
import com.example.demo.framework.ErrorCode;
import com.example.demo.framework.ResultData;
import com.example.demo.framework.base.BaseController;
import com.example.demo.framework.util.DoubleUtil;
import com.example.demo.framework.util.JodaUtil;
import com.example.demo.framework.util.QiniuHelper;
import com.example.demo.framework.util.SfUtil;
import com.example.demo.model.AfterSale;
import com.example.demo.model.Category;
import com.example.demo.model.Fund;
import com.example.demo.model.Item;
import com.example.demo.model.Logistics;
import com.example.demo.model.Order;
import com.example.demo.model.Sku;
import com.example.demo.model.Storage;
import com.example.demo.model.Trade;
import com.example.demo.model.UserInfo;
import com.example.demo.model.UserLevel;
import com.example.demo.repository.AfterSaleRepository;
import com.example.demo.repository.CategoryRepository;
import com.example.demo.repository.FundRepository;
import com.example.demo.repository.ItemRepository;
import com.example.demo.repository.LogisticsRepository;
import com.example.demo.repository.OrderRepository;
import com.example.demo.repository.SkuRepository;
import com.example.demo.repository.StorageRepository;
import com.example.demo.repository.TradeRepository;
import com.example.demo.repository.UserLevelRepository;
import com.example.demo.repository.UserRepository;
import com.example.demo.service.AfterSaleService;
import com.example.demo.service.ItemService;
import com.example.demo.service.TradeService;
import com.example.wanln.util.WanlnApi;
import com.example.wanln.util.WanlnConfig;

@RestController
@RequestMapping("admin")
public class AdminController extends BaseController {

	@Autowired
	private ItemRepository itemRepository;

	@Autowired
	private SkuRepository skuRepository;

	@Autowired
	private TradeRepository tradeRepository;

	@Autowired
	private CategoryRepository categoryRepository;

	@Autowired
	private LogisticsRepository logisticsRepository;

	@Autowired
	private UserRepository userRepository;

	@Autowired
	private FundRepository fundRepository;

	@Autowired
	private AfterSaleRepository afterSaleRepository;

	@Autowired
	private TradeService tradeService;

	@Autowired
	private AfterSaleService afterSaleService;

	@Autowired
	private ItemService itemService;

	@Autowired
	private UserLevelRepository userLevelRepository;

	@Autowired
	private OrderRepository orderRepository;

	@Autowired
	private StorageRepository storageRepository;

	/**
	 * 删除仓库
	 * 
	 * @return
	 */
	@Transactional
	@RequestMapping("delStorage")
	public Object delStorage(Long sID) {
		Map<String, Object> data = new HashMap<>();
		Storage s = storageRepository.getByID(sID);
		if (s == null) {
			return new ResultData(ErrorCode.ERROR_10113, null);
		}
		if (s.getStatus() == 0) {
			return new ResultData(ErrorCode.ERROR_10114, null);
		}
		s.setStatus(0);
		if (s.getsLevel() == 1) {
			storageRepository.updateStatusByParentID(s.getsID());
		}
		return new ResultData(data);
	}

	/**
	 * 编辑仓库
	 * 
	 * @param storage
	 * @return
	 */
	@Transactional
	@RequestMapping("editStorage")
	public Object editStorage(Storage storage) {
		Map<String, Object> data = new HashMap<>();
		Storage s = storageRepository.getByID(storage.getsID());
		if (s == null) {
			return new ResultData(ErrorCode.ERROR_10113, null);
		}
		if (s.getStatus() == 0) {
			return new ResultData(ErrorCode.ERROR_10114, null);
		}
		s.setStorageName(storage.getStorageName());
		s.setStorageCode(storage.getStorageCode());
		if (s.getsLevel() == 1) {
			storageRepository.updatePStorageNameAndPCodeByParentID(s.getStorageName(), s.getStorageCode(), s.getsID());
		}
		return new ResultData(data);
	}

	/**
	 * 添加仓库
	 * 
	 * @param storage
	 * @return
	 */
	@Transactional
	@RequestMapping("addStorage")
	public Object addStorage(Storage storage) {
		Map<String, Object> data = new HashMap<>();
		storage.setStatus(1);
		if (storage.getParentID() != null) {
			Storage s = storageRepository.getByID(storage.getParentID());
			if (s == null) {
				return new ResultData(ErrorCode.ERROR_10113, null);
			}
			storage.setsLevel(2);
			storage.setpStorageCode(s.getStorageCode());
			storage.setpStorageName(s.getStorageName());
		} else {
			storage.setsLevel(1);
		}
		storageRepository.save(storage);
		data.put("storage", storage);
		return new ResultData(data);
	}

	/**
	 * 查询仓库列表
	 * 
	 * @return
	 */
	@RequestMapping("findStorage")
	public Object findStorage() {
		Map<String, Object> data = new HashMap<>();
		data.put("list", storageRepository.findByStatus(1));
		return new ResultData(data);
	}

	/**
	 * 添加商品类目
	 * 
	 * @param category
	 * @return
	 */
	@Transactional
	@RequestMapping("addCategory")
	public Object addCategory(Category category) {
		Map<String, Object> data = new HashMap<>();
		Category verify = categoryRepository.getByCategoryID(category.getCategoryID());
		if (verify != null) {
			return new ResultData(ErrorCode.ERROR_10111, null);
		}
		category.setStatus(1);
		categoryRepository.save(category);
		category.setShopNick(WanlnConfig.SHOP_NICK);
		category.setSortOrder(category.getcID().intValue());
		data.put("category", category);

		// 推送万里牛
		JSONArray categories = new JSONArray();
		categories.add(category);
		log.info(categories.toJSONString());
		String wlnResponse = WanlnApi.wanlnApiCategoriesOpen(JSONArray.toJSONString(categories));
		log.info("万里牛商品类目推送结果：" + wlnResponse);
		return new ResultData(data);
	}

	/**
	 * 查询商品类目列表
	 * 
	 * @return
	 */
	@RequestMapping("findCategory")
	public Object findCategory() {
		Map<String, Object> data = new HashMap<>();
		data.put("list", categoryRepository.findByStatus(1));
		return new ResultData(data);
	}

	/**
	 * 添加商品信息
	 * 
	 * @param item
	 * @return
	 */
	@Transactional
	@RequestMapping("addItem")
	public Object addItem(Item item) {
		Map<String, Object> data = new HashMap<>();
		Item verify = itemRepository.getByItemID(item.getItemID());
		if (verify != null) {
			return new ResultData(ErrorCode.ERROR_10105, null);
		}
		item.setCreateTime(JodaUtil.now());
		item.setStatus(1);
		JSONArray array = JSON.parseArray(item.getSkuStr());
		JSONArray skuArry = new JSONArray();
		int itemQuantity = 0;
		for (int i = 0; i < array.size(); i++) {
			Sku sku = JSON.parseObject(array.get(i).toString(), new TypeReference<Sku>() {
			});
			if (sku.getWeight() == null) {
				if (item.getWeight() == null) {
					sku.setWeight(0D);
				}
				sku.setWeight(item.getWeight());
			}
			sku.setCreateTime(item.getCreateTime());
			sku.setModifiyTime(sku.getCreateTime());
			sku.setItemID(item.getItemID());
			sku.setStatus(1);
			sku.setImageURL(item.getImageURL());
			sku.setAttributes(sku.getAttributes() + ";" + sku.getAttributes2());
			skuRepository.save(sku);
			JSONObject skuObj = (JSONObject) JSONObject.toJSON(sku);
			skuObj.put("skuID", sku.getSkuID() + "");
			skuObj.remove("attributes2");
			skuArry.add(skuObj);
			itemQuantity += sku.getQuantity();
		}
		item.setSkuStr(skuArry.toJSONString());
		itemRepository.save(item);
		item.setShopNick(WanlnConfig.SHOP_NICK);
		item.setPrice(array.getJSONObject(0).getDouble("price"));
		item.setQuantity(itemQuantity);
		if (StringUtils.isEmpty(item.getItemURL())) {
			item.setItemURL(item.getImageURL());
		}
		item.setModifyTime(item.getCreateTime());
		data.put("item", item);

		// 推送万里牛
		JSONObject itemObj = (JSONObject) JSON.toJSON(item);
		itemObj.put("skus", skuArry);
		itemObj.remove("skuStr");
		itemObj.remove("skuJson");
		JSONArray items = new JSONArray();
		items.add(itemObj);
		log.info(items.toJSONString());
		String wlnResponse = WanlnApi.wanlnApiItemsOpen(JSON.toJSONString(items));
		log.info("万里牛商品信息推送结果：" + wlnResponse);
		return new ResultData(data);
	}

	/**
	 * 查询所有商品列表
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping("findItem")
	public Object findItem(@RequestParam(value = "pageNo", defaultValue = "0") int pageNo, Item item) {
		Map<String, Object> data = new HashMap<>();
		CustomPage page = itemService.findItem(pageNo(pageNo), PAGESIZE, item, null);
		if (page.getContent().size() > 0) {
			for (Object obj : page.getContent()) {
				Map<String, Object> m = (Map<String, Object>) obj;
				JSONArray array = JSON.parseArray((String) m.get("skuStr"));
				m.put("skuStr", "");
				m.put("skuJson", array);
			}
		}
		data.put("page", page);
		return new ResultData(data);
	}

	/**
	 * 商品编辑
	 * 
	 * @param item
	 * @return
	 */
	@RequestMapping("changeItem")
	public Object changeItem(Item item) {
		Map<String, Object> data = new HashMap<>();

		return new ResultData(data);
	}

	/**
	 * 商品上架
	 * 
	 * @param iID
	 * @return
	 */
	@RequestMapping("itemPutaway")
	public Object itemPutaway(long iID) {
		Map<String, Object> data = new HashMap<>();
		Item item = itemRepository.getByID(iID);
		if (item == null) {
			return new ResultData(ErrorCode.ERROR_10101, null);
		}
		item.setStatus(1);
		item.setModifyTime(JodaUtil.now());
		itemRepository.save(item);
		data.put("result", "操作成功");
		return new ResultData(data);
	}

	/**
	 * 商品下架
	 * 
	 * @param iID
	 * @return
	 */
	@RequestMapping("itemSoldOut")
	public Object itemSoldOut(long iID) {
		Map<String, Object> data = new HashMap<>();
		Item item = itemRepository.getByID(iID);
		if (item == null) {
			return new ResultData(ErrorCode.ERROR_10101, null);
		}
		item.setStatus(2);
		item.setModifyTime(JodaUtil.now());
		itemRepository.save(item);
		data.put("result", "操作成功");
		return new ResultData(data);
	}

	/**
	 * 商品删除
	 * 
	 * @param iID
	 * @return
	 */
	@RequestMapping("itemDel")
	public Object itemDel(long iID) {
		Map<String, Object> data = new HashMap<>();
		Item item = itemRepository.getByID(iID);
		if (item == null) {
			return new ResultData(ErrorCode.ERROR_10101, null);
		}
		if (item.getStatus() != 2) {
			return new ResultData(ErrorCode.ERROR_10102, null);
		}
		item.setStatus(0);
		item.setModifyTime(JodaUtil.now());
		itemRepository.save(item);
		data.put("result", "操作成功");
		return new ResultData(data);
	}

	/**
	 * 订单列表
	 * 
	 * @param pageNo
	 * @param trade
	 * @return
	 */
	@RequestMapping("orderList")
	public Object orderList(@RequestParam(value = "pageNo", defaultValue = "0") int pageNo, Trade trade,
			String username) {
		Map<String, Object> data = new HashMap<>();
		data.put("page", tradeService.findTradeOrder(pageNo(pageNo), PAGESIZE, trade, username));
		return new ResultData(data);
	}

	/**
	 * 订单详情
	 * 
	 * @param tID
	 * @return
	 */
	@RequestMapping("orderDetail")
	public Object orderDetail(long tID) {
		Map<String, Object> data = new HashMap<>();
		Map<String, Object> map = tradeRepository.getTradeOrder(tID);
		if (map != null) {
			if (map.get("express") != null && "顺丰".equals(map.get("express"))) {
				String xml = SfUtil.sfRouteQueryByOrderNo((String) map.get("logisticsNumber"));
				try {
					org.json.JSONObject xmlJSONObject = XML.toJSONObject(xml);
					JSONObject json = JSON.parseObject(xmlJSONObject.toString());
					data.put("logistics", json);
				} catch (JSONException e) {
					e.printStackTrace();
				}
			}
			data.put("orderDetail", map);
		}
		return new ResultData(data);
	}

	/**
	 * 订单发货
	 * 
	 * @param tID
	 * @return
	 */
	@Transactional
	@RequestMapping("deliverGoods")
	public Object deliverGoods(long tID, Logistics logistics) {
		Map<String, Object> data = new HashMap<>();
		Trade trade = tradeRepository.getByID(tID);
		if (trade == null) {
			new ResultData(ErrorCode.ERROR_10301, null);
		}
		if (trade.getStatus() != 2) {
			new ResultData(ErrorCode.ERROR_10302, null);
		}
		logistics.setTradeID(trade.getTradeID());
		logisticsRepository.save(logistics);
		trade.setStatus(5);
		trade.setShippingTime(JodaUtil.now());

		JSONArray ordersArry = new JSONArray();
		List<Order> list = orderRepository.findByTradeID(trade.getTradeID());
		for (Order o : list) {
			o.setStatus(5);
			ordersArry.add(o);
		}
		// 推送万里牛
		JSONObject tradeObj = (JSONObject) JSON.toJSON(trade);
		tradeObj.put("orders", ordersArry);
		JSONArray trades = new JSONArray();
		trades.add(tradeObj);
		log.info(trades.toJSONString());
		String wlnResponse = WanlnApi.wanlnApiTradesOpen(JSON.toJSONString(trades));
		log.info("万里牛订单发货推送结果：" + wlnResponse);
		return new ResultData(data);
	}

	/**
	 * 订单取消
	 * 
	 * @param tID
	 * @param sellerMemo
	 * @return
	 */
	@Transactional
	@RequestMapping("orderCancel")
	public Object orderCancel(long tID, String sellerMemo) {
		Map<String, Object> data = new HashMap<>();
		Trade trade = tradeRepository.getByID(tID);
		if (trade == null) {
			new ResultData(ErrorCode.ERROR_10301, null);
		}
		if (trade.getStatus() != 2) {
			new ResultData(ErrorCode.ERROR_10302, null);
		}
		if (trade.getHasRefund() == 1) {
			new ResultData(ErrorCode.ERROR_10303, null);
		}
		trade.setSellerMemo(sellerMemo);
		trade.setHasRefund(1);
		trade.setEndTime(JodaUtil.now());
		trade.setStatus(4);
		tradeRepository.save(trade);
		UserInfo user = userRepository.getOne(trade.getUserID());
		System.out.println(user.getUserID());
		System.out.println(user.getUserMoney());
		fundRepository.save(Fund.buildRefund(trade.getTradeID(), user.getUserID(), trade.getEndTime(),
				trade.getPayment(), user.getUserMoney(), DoubleUtil.add(user.getUserMoney(), trade.getPayment())));
		user.setSaleroom(DoubleUtil.sub(user.getSaleroom(), trade.getPayment()));
		user.setUserMoney(DoubleUtil.add(user.getUserMoney(), trade.getPayment()));
		userRepository.save(user);
		return new ResultData(data);
	}

	/**
	 * 处理售后
	 * 
	 * @return
	 */
	@Transactional
	@RequestMapping("handlingAfterSale")
	public Object handlingAfterSale(AfterSale as) {
		Map<String, Object> data = new HashMap<>();
		AfterSale afterSale = afterSaleRepository.getBytradeID(as.getTradeID());
		if (afterSale == null) {
			new ResultData(ErrorCode.ERROR_10351, null);
		}
		afterSale.setStatus(as.getStatus());
		afterSale.setChecktime(JodaUtil.now());
		afterSale.setReply(as.getReply());
		return new ResultData(data);
	}

	/**
	 * 售后列表
	 * 
	 * @return
	 */
	@RequestMapping("afterSaleList")
	public Object afterSaleList(@RequestParam(value = "pageNo", defaultValue = "0") int pageNo, String tradeID,
			String username, Integer status) {
		Map<String, Object> data = new HashMap<>();
		data.put("page",
				afterSaleService.findAfterSaleTrade(pageNo(pageNo), PAGESIZE, tradeID, null, username, status));
		return new ResultData(data);
	}

	/**
	 * 售后详情
	 * 
	 * @param tID
	 * @return
	 */
	@RequestMapping("afterSaleDetail")
	public Object afterSaleDetail(long tID) {
		Map<String, Object> data = new HashMap<>();
		data.put("afterSaleDetail", tradeRepository.getTradeOrder(tID));
		return new ResultData(data);
	}

	/**
	 * 代理商列表
	 * 
	 * @param pageNo
	 * @param userInfo
	 * @return
	 */
	@RequestMapping("findUserList")
	public Object findUserList(@RequestParam(value = "pageNo", defaultValue = "0") int pageNo, UserInfo userInfo) {
		Map<String, Object> data = new HashMap<>();
		userInfo.setUserType(1);
		Page<UserInfo> list = userRepository.pageCriteria(userInfo, new QPageRequest(pageNo(pageNo), PAGESIZE));
		data.put("list", list);
		return new ResultData(data);
	}

	/**
	 * 编辑代理商
	 * 
	 * @param userInfo
	 * @return
	 */
	@Transactional
	@RequestMapping("editUser")
	public Object editUser(UserInfo user) {
		Map<String, Object> data = new HashMap<>();
		UserInfo info = userRepository.getByUserID(user.getUserID());
		if (info == null) {
			return new ResultData(ErrorCode.ERROR_10202, null);
		}
		if (StringUtils.isNotEmpty(user.getPassword())) {
			info.setPassword(user.getPassword());
		}
		if (StringUtils.isNotEmpty(user.getPayPassword())) {
			info.setPassword(user.getPayPassword());
		}
		if (StringUtils.isNotEmpty(user.getPhone())) {
			info.setPayPassword(user.getPhone());
		}
		if (StringUtils.isNotEmpty(user.getPhone())) {
			info.setPhone(user.getPhone());
		}
		if (user.getUserLevel() != null) {
			info.setUserLevel(user.getUserLevel());
		}
		if (user.getuStatus() != null) {
			info.setuStatus(user.getuStatus());
		}
		data.put("userInfo", info);
		return new ResultData(data);
	}

	/**
	 * 查询级别列表
	 * 
	 * @return
	 */
	@RequestMapping("findUserLevel")
	public Object findUserLevel() {
		Map<String, Object> data = new HashMap<>();
		data.put("list", userLevelRepository.findAll());
		return new ResultData(data);
	}

	/**
	 * 修改级别折扣
	 * 
	 * @param level
	 * @return
	 */
	@Transactional
	@RequestMapping("editUserLevel")
	public Object editUserLevel(UserLevel level) {
		Map<String, Object> data = new HashMap<>();
		UserLevel ul = userLevelRepository.getByID(level.getUserLevel());
		if (ul == null) {
			return new ResultData(ErrorCode.ERROR_10401, null);
		}
		ul.setDiscount(level.getDiscount());
		userRepository.updateDiscountByLevel(level.getDiscount(), level.getUserLevel());
		return new ResultData(data);
	}

	/**
	 * 充值审核成功
	 * 
	 * @param fID
	 * @return
	 */
	@Transactional
	@RequestMapping("fundCheckSuccess")
	public Object fundCheckSuccess(long fID) {
		Map<String, Object> data = new HashMap<>();
		Fund fund = fundRepository.getByID(fID);
		if (fund == null) {
			return new ResultData(ErrorCode.ERROR_10501, null);
		}
		if (fund.getStatus() > 1) {
			return new ResultData(ErrorCode.ERROR_10502, null);
		}
		fund.setUpdateTime(JodaUtil.now());
		fund.setStatus(2);

		UserInfo fundUser = userRepository.getByUserID(fund.getuID());
		fundUser.setUserMoney(DoubleUtil.add(fundUser.getUserMoney(), fund.getChangeMoney()));

		return new ResultData(data);
	}

	/**
	 * 充值审核失败
	 * 
	 * @param fID
	 * @return
	 */
	@Transactional
	@RequestMapping("fundCheckFail")
	public Object fundCheckFail(long fID,String withNote) {
		Map<String, Object> data = new HashMap<>();
		Fund fund = fundRepository.getByID(fID);
		if (fund == null) {
			return new ResultData(ErrorCode.ERROR_10501, null);
		}
		if (fund.getStatus() > 1) {
			return new ResultData(ErrorCode.ERROR_10502, null);
		}
		fund.setWithNote(withNote);
		fund.setUpdateTime(JodaUtil.now());
		fund.setStatus(3);
		return new ResultData(data);
	}

	/**
	 * 管理员-充值记录
	 * 
	 * @param pageNo
	 * @return
	 */
	@RequestMapping("findRecords")
	public Object findRecordsList(@RequestParam(value = "pageNo", defaultValue = "0") int pageNo, Fund fund) {
		Map<String, Object> data = new HashMap<>();
		Page<Fund> list = fundRepository.pageCriteria(fund, new QPageRequest(pageNo(pageNo), PAGESIZE));
		data.put("list", list);
		return new ResultData(data);
	}

	/**
	 * 图片上传
	 * 
	 * @param file
	 * @param uploadType
	 * @return
	 */
	@RequestMapping("uploadImg")
	public Object uploadImg(@RequestParam("file") MultipartFile file, String uploadType) {
		Map<String, Object> data = new HashMap<>();
		if (file.isEmpty()) {
			return new ResultData(ErrorCode.ERROR_10054, null);
		}
		String filePath = "tyyp/admin/";
		String imgUrl = "";
		switch (uploadType) {
		case QiniuHelper.UPLOADTYPE_ITEM:
			filePath = filePath + QiniuHelper.UPLOADTYPE_ITEM;
			break;
		default:
			return new ResultData(ErrorCode.ERROR_10052, null);
		}
		if (file.getSize() > 1048576 * 5) {
			return new ResultData(ErrorCode.ERROR_10051, null);
		}
		byte[] byteData;
		try {
			byteData = file.getBytes();
			JSONObject obj = JSONObject.parseObject(QiniuHelper.uploadFile(byteData, createfilePathName(filePath)));
			if (!obj.containsKey("key")) {
				return new ResultData(ErrorCode.ERROR_10053, null);
			}
			imgUrl = QiniuHelper.domain + "/" + obj.getString("key");
			log.info("上传图片成功返回路径：" + imgUrl);
		} catch (IOException e) {
			e.printStackTrace();
		}
		data.put("imgUrl", imgUrl);
		return new ResultData(data);
	}

	private String createfilePathName(String filePath) {
		return filePath + "/" + UUID.randomUUID().toString().replaceAll("-", "") + ".jpg";
	}

}
